package graph;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.internal.corext.dom.Bindings;

public class InterfaceSearcher {
	
	private static List<IType> getAllITypes() throws JavaModelException {
		List<IType> iTypes = new LinkedList<IType>();
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRoot root = workspace.getRoot();
		IProject[] projects = root.getProjects();
		for (IProject project : projects) {
			IJavaProject javaProject = JavaCore.create(project);
			for (IPackageFragment mypackage : javaProject.getPackageFragments()) {
				if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) {
					for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
						iTypes.addAll(Arrays.asList(unit.getAllTypes()));
					}
				}
			}
		}
		return iTypes;
	}
		
	public static IType getInterface(List<IMethodBinding> methodBindings, boolean onlySpecifiedMethods) throws JavaModelException{
		for (IType iType : getAllITypes()) {
			if (iType.isInterface()) {
				int methodsFound = 0;
				for (IMethodBinding method : methodBindings) {
					IMethod foundMethod = Bindings.findMethod(method, iType);
					if (foundMethod!=null)
						methodsFound++;
				}
				if (methodsFound==methodBindings.size() &&  
					((methodsFound==iType.getMethods().length && onlySpecifiedMethods) || 
					(!onlySpecifiedMethods)))
					return iType;
			}
		}
        return null;
	}
}
